import re

from django.utils import timezone
from rest_framework import serializers
from django_redis import get_redis_connection
from rest_framework_jwt.settings import api_settings
from users.models import User, WriteArticle


class UserSignCreateSerializer(serializers.ModelSerializer):
    """用户注册的序列化器"""
    sms_code = serializers.CharField(max_length=6, min_length=6, write_only=True)
    password2 = serializers.CharField(max_length=16, min_length=4, write_only=True)
    password = serializers.CharField(max_length=16, min_length=4, )
    token = serializers.CharField(label='登录状态token', read_only=True)  # 增加token字段

    class Meta:
        model = User
        fields = ('id', 'username', 'password', 'mobile', 'sms_code', 'password2', 'token')

    def validate_username(self, value):
        """验证用户名是否是字母 数字 """
        # [0-9a-zA-Z_]{0,19}@[0-9a-zA-Z]{1,13}\.[com,cn,net]{1,3}    邮箱的正则
        if not re.match(r'^[a-zA-Z0-9_-]{4,16}$', value):
            raise serializers.ValidationError('用户名为字母,数字，不能有中文。')
        return value

    def validate_mobile(self, value):
        """验证手机号"""
        if not re.match(r'^1[3-9]\d{9}$', value):
            raise serializers.ValidationError('手机号格式错误')
        return value

    def validate(self, data):
        # 判断两次密码
        if data['password'] != data['password2']:
            raise serializers.ValidationError('两次密码不一致')

        # 判断短信验证码
        redis_conn = get_redis_connection('verify_codes')
        mobile = data['mobile']
        real_sms_code = redis_conn.get('sms_%s' % mobile)
        if real_sms_code is None:
            raise serializers.ValidationError('无效的短信验证码')
        if data['sms_code'] != real_sms_code.decode():
            raise serializers.ValidationError('短信验证码错误')
        return data

    def create(self, validated_data):
        """
        创建用户
        """
        # 移除数据库模型类中不存在的属性
        del validated_data['sms_code']
        del validated_data['password2']
        # print(validated_data['sms_code'])
        # 调用父类保存方法
        user = super().create(validated_data)
        # 调用django密码加密
        user.set_password(validated_data['password'])
        user.save()

        # 生成记录登录状态的token
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        user.token = token

        return user


class UserDetailSerializer(serializers.ModelSerializer):
    """用户详细信息序列化器"""

    class Meta:
        model = User
        fields = ('id', 'username', 'mobile', 'email', 'nickname', 'sex', 'address', 'email_active')


class EditDetailsCreateSerializer(serializers.ModelSerializer):
    """用户个人中心编辑资料提交保存的序列化器"""

    class Meta:
        model = User
        fields = ('nickname', 'sex', 'email', 'address')

    def update(self, instance, validated_data):
        nickname = validated_data['nickname']
        sex = validated_data['sex']
        address = validated_data['address']
        email = validated_data['email']

        instance.nickname = nickname
        instance.sex = sex
        instance.address = address
        instance.email = email
        instance.save()
        return instance


class WriteArticleSerializer(serializers.ModelSerializer):
    """用户写文章的序列化器"""

    class Meta:
        model = WriteArticle
        fields = ('article_name', 'article_classify', 'article_text')

    def create(self, validated_data):
        """
        创建文章
        """
        users_id = self.context['request'].user  # 获取用户对象
        # users_id = validated_data.get('users_id')
        article_text = validated_data['article_text']
        article_name = validated_data['article_name']
        article_classify = validated_data['article_classify']

        # user = super().create(validated_data)
        user = WriteArticle.objects.create(users_id=users_id, article_text=article_text, article_name=article_name,
                                           article_classify=article_classify)

        return user


class UpdateTimeSerializer(serializers.ModelSerializer):
    """用户个人中心编辑资料提交保存的序列化器"""

    class Meta:
        model = User
        fields = ('username',)

    def update(self, instance, validated_data):
        username = validated_data['username']
        instance.username = username
        instance.update_time = timezone.now()
        instance.last_login = timezone.now()
        instance.save()
        return instance


class MyArticleListSerializer(serializers.ModelSerializer):
    """用户我的文章列表序列化器"""

    update_time = serializers.CharField(label='文章更新时间字符串化', read_only=True)
    class Meta:
        model = WriteArticle
        fields = ('id', 'article_name', 'article_classify', 'update_time')


class MyArticleDetailSerializer(serializers.ModelSerializer):
    """文章详细信息序列化器"""
    update_time = serializers.CharField(label='文章更新时间字符串化', read_only=True)
    users_id = serializers.SlugRelatedField(label='文章用户名字', read_only=True, slug_field='username')

    class Meta:
        model = WriteArticle
        fields = ('id', 'article_name', 'article_classify', 'article_text', 'update_time', 'users_id')


class ArticleDeleteSerializer(serializers.ModelSerializer):
    """删除文章序列化器"""
    class Meta:
        model = WriteArticle
        fields = ('id', 'article_name', 'article_classify', 'article_text', 'update_time')


class GetArticleSerializer(serializers.ModelSerializer):
    """删除文章序列化器"""
    users_id = serializers.SlugRelatedField(label='文章用户名字', read_only=True, slug_field='username')
    update_time = serializers.CharField(label='文章更新时间字符串化', read_only=True)

    class Meta:
        model = WriteArticle
        fields = ('id', 'article_name', 'article_classify', 'article_text', 'update_time', 'users_id')